本來是想講講有哪些常用的內建EnvironmentValues
甚至是有哪些常用的property wrapper
但還是算了= =
今天就Demo一下
...也是不少了
首先我發現要改淺/深色模式是用.preferredColorScheme()這個modifier
但是它會“感染”到整個app
餵了一下狗發現還有另外一個modifier可以只改單個View
就是.colorScheme()
但他有以下限制
EDIT: 寫文章時發現原來用.environment(.colorScheme, .dark)就可以很輕易地改單個View了,囧
詳見
這個wrapper我們以前就有用過了
SwiftUI會提供一些內建的環境變數給我們讀取/使用
最常看到的是.presentationMode(但已被.dismiss取代)
而我們也可以用.colorScheme來判斷目前是在淺色還是深色模式
但它只能偵測.preferredColorScheme()的改變
.colorScheme()是不行的
上一節提到SwiftUI有內建一些變數給我們了
那麼我們是不是也可以自訂變數來用呢?
答案是肯定的
總共有兩個步驟
讀取的話一樣是用之前的@Environment
而寫入的話是用.environment()這個modifier
官方範例在這
但@Environment由下而上只能讀取,你在這層做的改變,只會從下層開始影響
如果想要自由(?)一點,就要用到下節說的@EnvironmentObject
要使用大逆不道的@EnvironmentObject
首先要用到我們最後一堂課才終於遇見的class
這個class必須comform ObservableObject(公眾人物)
裡面的屬性就是我們關心的資料,則要用@Published修飾(昭告天下)
接著用.environmentObject()這modifier注入
@EnvironmentObject就可以取得object,愛怎麼改就怎麼改了XD
那麼為什麼我們一開始說這玩意是大逆不道呢?
請見來自前輩的警告
其實我是覺得這東西跟Flutter的provider或BLoC滿像的☘️☘️☘️
都是用來一鍵改變整個app的東西
可以用改修改app的語系啦風格主題啦
應該是滿適合的
然後副作用是用了@EnvironmentObject之後
在XXX_Previews裡面也要用.environmentObject()注入一下
不然無法預覽= =
主要分成上下兩個部分
上半部橘色是觀察與控制colorScheme
第一個Toggle是綁定isCurrentPageDarkMode與更新.colorScheme()
第二個Toggle是綁定isWholeAppDarkMode與更新.preferredColorScheme()
然後為了解決.colorScheme()權重比.preferredColorScheme()高的問題
我在.onChange()用isWholeAppDarkMode覆寫isCurrentPageDarkMode
下半部藍色可以再分成兩個view
紅色是目前這個view
綠色是另外拆出來的subView
然後各自都觀察@Environment 跟 @EnvironmentObject 的影響
結果就是第一個Toggle只能改變subView是否紅字
而第二個Toggle不只這層下層,甚至連上層是否紅字都能掌控
詳細代碼請見以下截圖
開頭發的宏願
請見下方三個驚人連結(竟然還有人出了專門的網站XD)
SwiftUI Property Wrappers
[HACKING WITH SWIFT] Which SwiftUI property wrapper to choose in any situation
[HACKING WITH SWIFT] All SwiftUI property wrappers explained and compared
精彩大結局
https://github.com/mark33699/FDLS